package com.data.mall.utils;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class DelayTaskQueueManager {


    @Getter
    private static final DelayTaskQueueManager instance = new DelayTaskQueueManager();
    /**
     * 延时队列
     */
    private final DelayQueue<DelayTask<?>> delayQueue;
    /**
     * 守护线程
     */
    private Thread daemonThread;

    private DelayTaskQueueManager() {
        delayQueue = new DelayQueue<>();
        init();
    }

/*
    public static DelayTaskQueueManager getInstance() {
        if (null == instance) {
            lock.lock();
            try {
                if (null == instance) {
                    instance = new DelayTaskQueueManager();
                }
            } finally {
                lock.unlock();
            }
        }
        return instance;
    }
*/

    /**
     * 初始化
     */
    public void init() {
        daemonThread = new Thread(() -> {
            execute();
        });
        daemonThread.setName("DelayQueueMonitor");
        daemonThread.start();
        log.info("延时队列管理器初始化完成...");
    }

    private void execute() {
        while (true) {
            Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
            log.info("当前存活线程数量:" + map.size());
            int taskNum = delayQueue.size();
            log.info("当前延时任务数量:" + taskNum);
            try {
                DelayTask<?> delayOrderTask = delayQueue.take();
                if (delayOrderTask != null) {
                    Runnable task = delayOrderTask.getTask();
                    if (null == task) {
                        continue;
                    }
                    // 提交到线程池执行task
                    ExecutorManager.getInstance().execute(task);
                }
            } catch (Exception e) {
                log.error("监控延长队列线程异常!!!", e);
            }
        }
    }

    /**
     * 添加任务
     *
     * @param task
     * @param time 延时时间
     * @param unit 时间单位
     */
    public void put(Runnable task, long time, TimeUnit unit) {
        long timeout = TimeUnit.NANOSECONDS.convert(time, unit);
        DelayTask<?> delayOrder = new DelayTask<>(timeout, task);
        delayQueue.put(delayOrder);
    }

    private static Map<String, AtomicInteger> adderTimes = new ConcurrentHashMap<>();
    static Object lock = new Object();

    public void put(String key, int count, Runnable task, long time, TimeUnit unit) {
        synchronized (lock) {
            if (adderTimes.containsKey(key)) {
                int i = adderTimes.get(key).incrementAndGet();
                if (i > count) {
                    adderTimes.remove(key);
                    return;
                }
            }
        }
        long timeout = TimeUnit.NANOSECONDS.convert(time, unit);
        DelayTask<?> delayOrder = new DelayTask<>(timeout, task);
        delayQueue.put(delayOrder);
    }

    /**
     * 删除任务
     *
     * @param task
     * @return
     */
    public boolean removeTask(DelayTask task) {
        return delayQueue.remove(task);
    }
}